package org.jahia.sqlprofiler.gui;

import org.jCharts.Chart;
import org.jahia.sqlprofiler.QueryEntry;
import java.util.Iterator;
import java.util.ArrayList;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.jCharts.chartData.DataSeries;
import java.awt.Paint;
import java.awt.Color;
import org.jCharts.chartData.AxisChartDataSet;
import org.jCharts.types.ChartType;
import org.jCharts.chartData.ChartDataException;
import org.jCharts.axisChart.AxisChart;
import org.jCharts.properties.LineChartProperties;
import org.jCharts.properties.ChartProperties;
import org.jCharts.properties.AxisProperties;
import org.jCharts.properties.LegendProperties;
import java.awt.Stroke;
import java.awt.Shape;
import java.awt.Dimension;
import java.util.SortedSet;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: Jahia Ltd</p>
 * @author not attributable
 * @version 1.0
 */

public class QueryTrafficChartModel extends AbstractChartModel {

    private static final org.apache.log4j.Logger logger = org.apache.log4j.
        Logger.getLogger(QueryTrafficChartModel.class);

    private ProfileStatementTableModel profileStatementModel;

    private long inboundTotalBytes = 0;
    private long outboundTotalBytes = 0;

    private int lastQueryTotal = 0;
    private LineChartProperties lineChartProperties;
    private ChartProperties chartProperties = new ChartProperties();
    private AxisProperties axisProperties = new AxisProperties();
    private LegendProperties legendProperties = new LegendProperties();
    private DataSeries dataSeries = null;

    public QueryTrafficChartModel(ProfileStatementTableModel
                                profileStatementModel) {

        this.profileStatementModel = profileStatementModel;
        Stroke[] strokes = {
            LineChartProperties.DEFAULT_LINE_STROKE,
            LineChartProperties.DEFAULT_LINE_STROKE
        };
        Shape[] shapes = {
            null,
            null
        };
        lineChartProperties = new
            LineChartProperties(strokes, shapes);
    }

    public Chart getChart(Dimension dimension) {
        if (dataSeries == null) {
            return null;
        }
        AxisChart axisChart = new AxisChart(dataSeries, chartProperties,
                                            axisProperties, legendProperties,
                                            (int) dimension.getWidth(),
                                            (int) dimension.getHeight());
        return axisChart;
    }

    public void update() {

        if (profileStatementModel.getQueryEntries().size() == lastQueryTotal) {
            return;
        }
        lastQueryTotal = profileStatementModel.getQueryEntries().size();

        try {

            long lowestTime = profileStatementModel.getLowestQueryTime();
            long highestTime = profileStatementModel.getHighestQueryTime();

            if ( (lowestTime != Long.MAX_VALUE) &&
                (highestTime != Long.MIN_VALUE)) {

                double timeInterval = highestTime - lowestTime;
                //final int slices = 100;
                // double timeIncrement = timeInterval / ((double) slices);
                double timeIncrement = 1000;
                double sliceCount = timeInterval / timeIncrement;
                int slices = new Double(sliceCount).intValue();

                if (slices < 2) {
                    return;
                }

                String[] xAxisLabels = new String[slices];
                double[][] data = new double[2][slices];

                int curSlice = 0;
                inboundTotalBytes = 0;
                outboundTotalBytes = 0;
                SortedSet sortedQueryEntries = profileStatementModel.getSortedQueryEntries();
                Iterator queryIter = sortedQueryEntries.iterator();
                double curSampleStartTime = lowestTime;
                double curSampleEndTime = lowestTime + timeIncrement;
                while (queryIter.hasNext()) {
                    QueryEntry curEntry = (QueryEntry) queryIter.next();
                    while (curEntry.getTime() > curSampleEndTime) {
                        xAxisLabels[curSlice] = Long.toString(new Double(
                            curSampleStartTime-lowestTime).longValue());
                        data[0][curSlice] = outboundTotalBytes;
                        data[1][curSlice] = inboundTotalBytes;
                        inboundTotalBytes = 0;
                        outboundTotalBytes = 0;
                        curSlice++;
                        curSampleStartTime = lowestTime +
                            timeIncrement * ( (double) curSlice);
                        curSampleEndTime = lowestTime +
                            timeIncrement * ( (double) curSlice + 1);
                    }
                    if (curEntry.getCategory() != null) {
                        if (curEntry.getCategory().toLowerCase().equals("statement")) {
                            outboundTotalBytes += curEntry.getSqlStatement().length();
                        } else if (curEntry.getCategory().toLowerCase().equals(
                            "resultset")) {
                            inboundTotalBytes += curEntry.getSqlStatement().length();
                        }
                    }
                }

                String xAxisTitle = "Milliseconds";
                String yAxisTitle = "Bytes";
                String title = "Query traffic over time";
                dataSeries = new DataSeries(xAxisLabels, xAxisTitle,
                                            yAxisTitle, title);

                String[] legendLabels = {
                    "Outgoing bytes / second",
                    "Incoming bytes / second"
                };
                Paint[] paints = {
                    Color.blue, Color.red
                };

                AxisChartDataSet axisChartDataSet = new AxisChartDataSet(data,
                    legendLabels, paints, ChartType.LINE, lineChartProperties);
                dataSeries.addIAxisPlotDataSet(axisChartDataSet);

                fireChartDataChanged();

            }

        } catch (ChartDataException chartDataException) {
            chartDataException.printStackTrace();
        }
    }

}